package org.dkakunsi.aplikasitoko.form.admin;

import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import org.dkakunsi.aplikasitoko.data.entity.Barang;
import org.dkakunsi.aplikasitoko.data.entity.Kasir;
import org.dkakunsi.aplikasitoko.data.entity.Supplier;
import org.dkakunsi.aplikasitoko.data.util.ApplicationDataException;
import org.dkakunsi.aplikasitoko.form.Desktop;
import org.dkakunsi.aplikasitoko.form.MyForm;
import org.dkakunsi.aplikasitoko.service.DataService;

public abstract class FormData extends MyForm {

	private static final long serialVersionUID = 1L;
	private boolean T = true;
	private boolean F = false;

	protected JLabel label;
	protected JLabel label_1;
	protected JLabel label_2;
	protected JLabel label_3;
	protected JLabel label_4;
	protected JTextField textField;
	protected JTextField textField_1;
	protected JTextField textField_2;
	protected JTextField textField_3;
	protected JTextField textField_4;
	protected JButton btnAdd;
	protected JButton btnSave;
	protected JButton btnUpdate;
	protected JButton btnDelete;
	protected JButton btnReset;
	protected JButton btnCari;
	
	protected List<Object> lsLoaded;
	protected List<Object> lsAdded = new ArrayList<>();
	protected List<Object> lsUpdated = new ArrayList<>();
	protected List<Object> lsDeleted = new ArrayList<>();

	
	/**
	 * create frame, with Desktop inizialized
	 * @param judul
	 */
	public FormData(String judul) {
		super(judul);
		setter();
	}

	/**
	 * create frame, with Desktop inizialized
	 * @param judul
	 * @param desktop
	 */
	public FormData(String judul, Desktop desktop) {
		super(judul, desktop);
		setter();
	}
	
	private void setter(){
		label = new JLabel("Kode");
		label.setBounds(680, 12, 100, 25);
		getContentPane().add(label);
		
		textField = new JTextField();
		textField.setBounds(790, 12, 110, 25);
		getContentPane().add(textField);
		textField.setColumns(10);
		
		label_1 = new JLabel("Nama");
		label_1.setBounds(680, 49, 100, 25);
		getContentPane().add(label_1);

		textField_1 = new JTextField();
		textField_1.setBounds(790, 49, 188, 25);
		getContentPane().add(textField_1);
		textField_1.setColumns(10);
		
		label_2 = new JLabel("Harga Jual");
		label_2.setBounds(680, 86, 100, 25);
		getContentPane().add(label_2);

		textField_2 = new JTextField();
		textField_2.setBounds(790, 86, 188, 25);
		getContentPane().add(textField_2);
		textField_2.setColumns(10);
		
		label_3 = new JLabel("Harga Beli");
		label_3.setBounds(680, 123, 100, 25);
		getContentPane().add(label_3);

		textField_3 = new JTextField();
		textField_3.setBounds(790, 123, 188, 25);
		getContentPane().add(textField_3);
		textField_3.setColumns(10);
		
		label_4 = new JLabel("Jumlah");
		label_4.setBounds(680, 160, 100, 25);
		getContentPane().add(label_4);

		textField_4 = new JTextField();
		textField_4.setBounds(790, 160, 188, 25);
		getContentPane().add(textField_4);
		textField_4.setColumns(10);
		
		btnCari = new JButton("CARI");
		btnCari.setBounds(913, 12, 65, 25);
		getContentPane().add(btnCari);
		btnCari.setActionCommand("SEARCH");
		btnCari.addActionListener(this);
		
		btnAdd = new JButton("ADD");
		btnAdd.setBounds(12, 210, 100, 25);
		getContentPane().add(btnAdd);
		btnAdd.setActionCommand("ADD");
		btnAdd.addActionListener(this);
		
		btnSave = new JButton("SAVE");
		btnSave.setBounds(320, 210, 100, 25);
		getContentPane().add(btnSave);
		btnSave.setActionCommand("SAVE");
		btnSave.addActionListener(this);
		
		btnUpdate = new JButton("UPDATE");
		btnUpdate.setBounds(170, 210, 100, 25);
		getContentPane().add(btnUpdate);
		btnUpdate.setActionCommand("UPDATE");
		btnUpdate.addActionListener(this);
		
		btnDelete = new JButton("DELETE");
		btnDelete.setBounds(475, 210, 100, 25);
		getContentPane().add(btnDelete);
		btnDelete.setActionCommand("DELETE");
		btnDelete.addActionListener(this);
		
		btnReset = new JButton("RESET");
		btnReset.setBounds(635, 210, 100, 25);
		getContentPane().add(btnReset);
		btnReset.setActionCommand("RESET");
		btnReset.addActionListener(this);

		initializeButtonView(T, F, F, F, F, T);
		initializeTextView(T, F, F, F, F);
		
		ds = new DataService();
	}
	
	protected void setKasir(){
		label_4.setVisible(false);
		textField_4.setVisible(false);
		label_3.setVisible(false);
		textField_3.setVisible(false);
		label_2.setText("Password");
	}

	protected void setSupplier(){
		setKasir();
		label_2.setVisible(false);
		textField_2.setVisible(false);
	}
	
	private void initializeButtonView(boolean b1, boolean b2, boolean b3,
			boolean b4, boolean b5, boolean b6){
		this.btnAdd.setEnabled(b1);
		this.btnUpdate.setEnabled(b2);
		this.btnSave.setEnabled(b3);
		this.btnDelete.setEnabled(b4);
		this.btnReset.setEnabled(b5);
		this.btnCari.setEnabled(b6);
	}

	private void initializeTextView(boolean b1, boolean b2, boolean b3,
			boolean b4, boolean b5){
		this.textField.setEnabled(b1);
		this.textField_1.setEnabled(b2);
		this.textField_2.setEnabled(b3);
		this.textField_3.setEnabled(b4);
		this.textField_4.setEnabled(b5);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();

		switch(command){
			case "EXIT" :
				saveBeforeExit();
				exit();
				break;
			case "ADD" : 
				initializeButtonView(F, F, T, F, T, F);
				initializeTextView(T, T, T, T, T);
				add();
				break;
			case "SAVE" :
				initializeButtonView(T, F, F, F, F, T);
				initializeTextView(T, F, F, F, F);
				save();
				break;
			case "UPDATE" :
				initializeButtonView(F, F, T, F, T, F);
				initializeTextView(F, T, T, T, T);
				update();
				break;
			case "DELETE" : 
				initializeButtonView(T, F, F, F, F, T);
				initializeTextView(T, F, F, F, F);
				delete();
				break;
			case "RESET" :
				initializeButtonView(T, F, F, F, F, T);
				initializeTextView(T, F, F, F, F);
				reset();
				break;
			case "SEARCH" :
				try {
					search(textField.getText());
					initializeButtonView(F, T, F, T, T, F);
				} catch (ApplicationDataException e1) {
					JOptionPane.showMessageDialog(this, e1.getMessage(), "Kesalahan Kode", JOptionPane.ERROR_MESSAGE);
				}
				break;
			default :
				break;
		}
	}

	protected void saveBeforeExit() {
		Object object = null;
		
		Iterator<Object> itA = lsAdded.iterator();
		Iterator<Object> itU = lsUpdated.iterator();
		Iterator<Object> itD = lsDeleted.iterator();

		// deleting
		while(itD.hasNext()){
			object = itD.next();
//			barang.getListTransaksiBarang().clear();
			
			try {
				ds.delete(object);
			} catch (ApplicationDataException e) {
				JOptionPane.showMessageDialog(this, "Call the Developer", "Application Error", JOptionPane.ERROR_MESSAGE);
//				e.printStackTrace();
			}
		}

		// merging
		while(itU.hasNext()){
			object = itU.next();
			
			try {
				ds.update(object);
			} catch (ApplicationDataException e) {
				JOptionPane.showMessageDialog(this, "Call the Developer", "Application Error", JOptionPane.ERROR_MESSAGE);
//				e.printStackTrace();
			}
		}
		
		// saving
		while(itA.hasNext()){
			object = itA.next();

			try {
				ds.save(object);
			} catch (ApplicationDataException e) {
				JOptionPane.showMessageDialog(this, "Call the Developer", "Application Error", JOptionPane.ERROR_MESSAGE);
//				e.printStackTrace();
			}
		}
	}
	protected void load(Object objFound, Object object){
		try {
			if( objFound != null ){
				lsLoaded.remove(objFound);
			}
			if( object != null){
				lsLoaded.add(object);
			}
		} catch(NullPointerException exc){
			JOptionPane.showMessageDialog(this, "NullPointerException @ FormData.load()", "Debugging", JOptionPane.DEFAULT_OPTION);
		}
		loadView();
	}

	@SuppressWarnings({ "rawtypes" })
	protected boolean isExistInList(List list, Object obj, boolean initialize){
		boolean canDo = initialize;
		Barang barang = null;
		Kasir kasir= null;
		Supplier supplier= null;
		
		Iterator itList = list.iterator();
		while(itList.hasNext()){
			if(obj instanceof Barang){
				barang = (Barang) obj;
				Barang barangFound = (Barang) itList.next();
				if(barangFound.getKode().equals(barang.getKode())){
					canDo = !initialize;
					break;
				}
			} else if(obj instanceof Kasir){
				kasir = (Kasir) obj;
				Kasir kasirFound = (Kasir) itList.next();
				if(kasirFound.getKode().equals(kasir.getKode())){
					canDo = !initialize;
					break;
				}
			} else if(obj instanceof Supplier){
				supplier = (Supplier) obj;
				Supplier supplierFound = (Supplier) itList.next();
				if(supplierFound.getKode().equals(supplier.getKode())){
					canDo = !initialize;
					break;
				}
			}
		}

		return canDo;
	}

	protected abstract void add();
	protected abstract void save();
	protected abstract void update();
	protected abstract void delete();
	protected abstract void reset();
	protected abstract void search(String id) throws ApplicationDataException;

}
